package com.jijuxie.common.service.impl;

import com.jijuxie.common.service.MapService;
import com.jijuxie.common.domain.Coordinate;
import com.jijuxie.common.domain.Address;
import com.jijuxie.common.exception.ServiceException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

@Service
public class AMapServiceImpl implements MapService {

    private static final Logger log = LoggerFactory.getLogger(AMapServiceImpl.class);

    @Value("${amap.key}")
    private String key;

    private final RestTemplate restTemplate = new RestTemplate();

    @Override
    public Coordinate geocoder(String address) {
        if (address == null || address.trim().isEmpty()) {
            log.warn("地址为空，无法进行地理编码");
            throw new ServiceException("地址不能为空");
        }

        try {
            // 调用高德地图 API
            String url = String.format(
                    "https://restapi.amap.com/v3/geocode/geo?address=%s&key=%s&output=json",
                    URLEncoder.encode(address, StandardCharsets.UTF_8),
                    key
            );

            log.info("发送地理编码请求: {}", url);
            Map<String, Object> response = restTemplate.getForObject(url, Map.class);
            
            if (response == null) {
                log.error("调用高德地图API返回结果为空");
                throw new ServiceException("地图服务异常");
            }

            String status = (String) response.get("status");
            if (!"1".equals(status)) {
                log.error("高德地图API调用失败: {}", response);
                throw new ServiceException("地理编码服务异常: " + response.get("info"));
            }

            // 解析结果
            Integer count = Integer.parseInt(response.get("count").toString());
            if (count == 0) {
                log.warn("未找到匹配的地址: {}", address);
                throw new ServiceException("未找到匹配的地址位置信息");
            }

            // 获取第一个匹配结果
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> geocodes = (List<Map<String, Object>>) response.get("geocodes");
            Map<String, Object> geocode = geocodes.get(0);
            
            // 获取经纬度字符串，格式为"经度,纬度"
            String location = (String) geocode.get("location");
            String[] lngLat = location.split(",");
            
            log.info("地址 {} 解析成功，经纬度: {}", address, location);
            return new Coordinate(
                    new BigDecimal(lngLat[0]), // 经度
                    new BigDecimal(lngLat[1])  // 纬度
            );
        } catch (ServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("地理编码异常", e);
            throw new ServiceException("地理编码服务异常: " + e.getMessage());
        }
    }

    @Override
    public Address reverseGeocoder(BigDecimal lng, BigDecimal lat) {
        if (lng == null || lat == null) {
            log.warn("经纬度为空，无法进行逆地理编码");
            throw new ServiceException("经纬度不能为空");
        }

        try {
            // 调用高德地图 API
            String url = String.format(
                    "https://restapi.amap.com/v3/geocode/regeo?location=%s,%s&key=%s&extensions=base&output=json",
                    lng, lat, key
            );

            log.info("发送逆地理编码请求: {}", url);
            Map<String, Object> response = restTemplate.getForObject(url, Map.class);
            
            if (response == null) {
                log.error("调用高德地图API返回结果为空");
                throw new ServiceException("地图服务异常");
            }

            String status = (String) response.get("status");
            if (!"1".equals(status)) {
                log.error("高德地图API调用失败: {}", response);
                throw new ServiceException("逆地理编码服务异常: " + response.get("info"));
            }

            // 解析结果
            @SuppressWarnings("unchecked")
            Map<String, Object> regeocode = (Map<String, Object>) response.get("regeocode");
            if (regeocode == null || regeocode.isEmpty()) {
                log.warn("未找到匹配的位置信息: {},{}", lng, lat);
                throw new ServiceException("未找到匹配的位置信息");
            }

            @SuppressWarnings("unchecked")
            Map<String, Object> addressComponent = (Map<String, Object>) regeocode.get("addressComponent");
            
            String province = (String) addressComponent.get("province");
            String city = (String) addressComponent.get("city");
            String district = (String) addressComponent.get("district");
            String street = (String) addressComponent.get("township");
            
            log.info("经纬度 {},{} 解析成功", lng, lat);
            return new Address(province, city, district, street);
        } catch (ServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("逆地理编码异常", e);
            throw new ServiceException("逆地理编码服务异常: " + e.getMessage());
        }
    }
}
